80990e0374fc2d46662fa03c442a43e040c47b99,source/com/intellij/psi/impl/PsiClassImplUtil.java,PsiClassImplUtil,buildAllMaps,#PsiClass#Class#,212

Before Change


  }

  private static <T extends PsiNamedElement> Map<String, List<Pair<T, PsiSubstitutor>>> buildAllMaps(final PsiClass psiClass, Class<T> type) {
    if (!psiClass.isPhysical()) return getMapInner(psiClass, type);
    final Object data;
    synchronized (PsiLock.LOCK) {
      data = psiClass.getUserData(ALL_MAPS_BUILT_FLAG);
    }

    if (data != null) {
      final Map<String, List<Pair<T, PsiSubstitutor>>> mapInner = getMapInner(psiClass, type);
      if (mapInner.isEmpty()) {
        LOG.assertTrue(false);
      }
      return mapInner;
    }

    final List<Pair<PsiClass, PsiSubstitutor>> classes = new ArrayList<Pair<PsiClass, PsiSubstitutor>>();
    final List<Pair<PsiField, PsiSubstitutor>> fields = new ArrayList<Pair<PsiField, PsiSubstitutor>>();
    final List<Pair<PsiMethod, PsiSubstitutor>> methods = new ArrayList<Pair<PsiMethod, PsiSubstitutor>>();


    final List<MethodCandidateInfo> list = new ArrayList<MethodCandidateInfo>();
    processDeclarationsInClassNotCached(psiClass, new FilterScopeProcessor(new OrFilter(new ElementFilter[]{
      new ClassFilter(PsiMethod.class),
      new ClassFilter(PsiField.class),
      new ClassFilter(PsiClass.class)
    }), null, list) {
      protected void add(PsiElement element, PsiSubstitutor substitutor) {
        if (element instanceof PsiMethod) {
          methods.add(new Pair<PsiMethod, PsiSubstitutor>((PsiMethod)element, substitutor));
        }
        else if (element instanceof PsiField) {
          fields.add(new Pair<PsiField, PsiSubstitutor>((PsiField)element, substitutor));
        }
        else if (element instanceof PsiClass) {
          classes.add(new Pair<PsiClass, PsiSubstitutor>((PsiClass)element, substitutor));
        }
      }
    }, PsiSubstitutor.EMPTY, new HashSet<PsiClass>(), null, psiClass, false);

    synchronized (PsiLock.LOCK) {
      //This is quite a critical doubled check. Actually, the first check might be removed
//But at least one check should be performed inside the non-cancelable action
//In order not to put uncomplete data to map
      if (psiClass.getUserData(ALL_MAPS_BUILT_FLAG) != null) {
        final Map<String, List<Pair<T, PsiSubstitutor>>> mapInner = getMapInner(psiClass, type);
        if (mapInner.isEmpty()) {
          LOG.assertTrue(false);
        }
        return mapInner;
      }
      final Map<String, List<Pair<PsiClass, PsiSubstitutor>>> classesMap = getMapInner(psiClass, PsiClass.class);
      final Map<String, List<Pair<PsiField, PsiSubstitutor>>> fieldsMap = getMapInner(psiClass, PsiField.class);
      final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> methodsMap = getMapInner(psiClass, PsiMethod.class);
      if (classesMap.isEmpty()) {
        generateMapByList(classesMap, classes);
      }
      ;
      if (fieldsMap.isEmpty()) {
        generateMapByList(fieldsMap, fields);
      }
      ;

After Change



    synchronized (PsiLock.LOCK) {
      Map<Class<? extends PsiMember>, Map<String, List>> result = new HashMap<Class<? extends PsiMember>, Map<String, List>>(3);
      result.put(PsiClass.class, generateMapByList(classes));
      result.put(PsiMethod.class, generateMapByList(methods));
      result.put(PsiField.class, generateMapByList(fields));
      psiClass.putUserData(ALL_MAPS_BUILT_FLAG, "");